/*
 * Cinta13A.h
 *
 *  Created on: Dec 1, 2013
 *      Author: m
 */

#ifndef CINTA13A_H_
#define CINTA13A_H_

#include "Semaphore.h"
#include "SharedMemory2.h"
#include "Cinta3Slots.h"
#include "DSMManager.h"

using ipc::Semaphore;
using ipc::SharedMemory2;

class Cinta13A
{
public:
    static const std::string s_ipcBaseFile;
    static const char s_cintaKey;
    static const char s_mtxCintaKey;
    static const char s_semProductorKey1;
    static const char s_semProductorKey2;
    static const char s_semConsumidorKey1;
    static const char s_semConsumidorKey2;

protected:
    Cinta3Slots* m_cinta;
    Semaphore m_mtxCinta;
    Semaphore m_semProductor1;
    Semaphore m_semProductor2;
    Semaphore m_semConsumidor1;
    Semaphore m_semConsumidor2;

public:

    Cinta13A() :
        m_cinta( SharedMemory2<Cinta3Slots>::get( s_ipcBaseFile, s_cintaKey )),
        m_mtxCinta( Semaphore::get( s_ipcBaseFile, s_mtxCintaKey ) ),
        m_semProductor1( Semaphore::get( s_ipcBaseFile, s_semProductorKey1 ) ),
        m_semProductor2( Semaphore::get( s_ipcBaseFile, s_semProductorKey2 ) ),
        m_semConsumidor1( Semaphore::get( s_ipcBaseFile, s_semConsumidorKey1 ) ),
        m_semConsumidor2( Semaphore::get( s_ipcBaseFile, s_semConsumidorKey2 ) )
    {
    }

    virtual ~Cinta13A()
    {
    }

    void iniciarExclusionMutua()
    {
        //m_mtxCinta.p();
        DSMManager::pedir( DSMID_CINTA13A );
    }

    void terminarExclusionMutua()
    {
        //m_mtxCinta.v();
        DSMManager::liberar( DSMID_CINTA13A );
    }

    void dormirProductor()
    {
        m_semProductor2.p();
    }

    void dormirConsumidor()
    {
        m_semConsumidor2.p();
    }

    void despertarProductor()
    {
        m_semProductor1.v();
    }

    void despertarConsumidor()
    {
        m_semConsumidor1.v();
    }

    Cinta3Slots* getCinta()
    {
        return m_cinta;
    }

    static void create()
    {
        *SharedMemory2<Cinta3Slots>::create( s_ipcBaseFile, s_cintaKey ) = Cinta3Slots();
        Semaphore::create( s_ipcBaseFile, s_mtxCintaKey ).initialize(1);
        Semaphore::create( s_ipcBaseFile, s_semProductorKey1 ).initialize(0);
        Semaphore::create( s_ipcBaseFile, s_semProductorKey2 ).initialize(0);
        Semaphore::create( s_ipcBaseFile, s_semConsumidorKey1 ).initialize(0);
        Semaphore::create( s_ipcBaseFile, s_semConsumidorKey2 ).initialize(0);
    }

    static void destroy()
    {
        SharedMemory2<Cinta3Slots>::destroy( s_ipcBaseFile, s_cintaKey );
        Semaphore::destroy( s_ipcBaseFile, s_mtxCintaKey );
        Semaphore::destroy( s_ipcBaseFile, s_semProductorKey1 );
        Semaphore::destroy( s_ipcBaseFile, s_semProductorKey2 );
        Semaphore::destroy( s_ipcBaseFile, s_semConsumidorKey1 );
        Semaphore::destroy( s_ipcBaseFile, s_semConsumidorKey2 );
    }
};

#endif /* CINTA13A_H_ */
